﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;

using LowLevelGraphics.Histograms;

namespace LowLevelGraphics.Filter
{
    public class Backprojection : BaseImageFilter
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="Backprojection"/> class.
        /// </summary>
        public Backprojection()
        {
       
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Backprojection"/> class.
        /// </summary>
        internal Backprojection(Backprojection _backprojection)
        {
        }

        /// <summary>
        /// Execute this Filter
        /// A Debug Statement is written if a concrete Filter is called
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            Histogram sourceHistogram = new Histogram(10, _bitmap);
            Histogram frameHistogram = new Histogram(10, _bitmap);
            int nWidth = _bitmap.Width;
            int nHeight = _bitmap.Height;
            int nIndex = 0;

            UnsafeBitmap fastBitmap = (UnsafeBitmap)_bitmap.Clone();
            UnsafeBitmap fastBitmapBP = _bitmap;

            byte val = 0;
            for (int y = 0; y < nHeight; y++)
            {
                for (int x = 0; x < nWidth; x++)
                {
                    Color pPixel = fastBitmap[x, y];
                    Color pPixelBP = fastBitmapBP[x, y];
                    //get the bin index for the current pixel colour
                    nIndex = sourceHistogram.GetSingleBinIndex(sourceHistogram.BinCount1,
                          sourceHistogram.BinCount2, sourceHistogram.BinCount3, pPixel);

                    //find the value for backprojection image and set
                    if (frameHistogram.Data[nIndex] > 0) //avoid divide by zero error
                        val = (byte)(255 * (int)(sourceHistogram.Data[nIndex] /
                                                 frameHistogram.Data[nIndex]));
                    else
                        val = 0;


                    fastBitmapBP[x, y] = Color.FromArgb(val, val, val);
                }
            }
            return fastBitmapBP;
        }
        /// <summary>
        /// This is used to clone a filter, each filter must implement it's own clone functionality
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new Backprojection(this);
        }
    }
}
